package models

import (
	"errors"
	"gorm.io/gorm"
	"time"
)

const (
	Unload = "unload"
	Loaded = "loaded"
	Finish = "finish"
)

var ErrRowsAffected = errors.New("rows affected is zero")

type Task struct {
	ID             int       `gorm:"primaryKey" json:"id"`
	CreatedAt      time.Time `json:"created_at"`                    // 创建时间
	UpdatedAt      time.Time `json:"updated_at"`                    // 更新时间
	UniqueKey      string    `gorm:"uniqueIndex" json:"unique_key"` // 唯一键
	Url            string    `json:"url"`                           // 请求链接
	Params         string    `json:"params"`                        // 请求参数
	ParserFunction string    `json:"parser_function"`               // 解析方法
	FailedReason   string    `json:"failed_reason"`                 // 失败原因
	Status         string    `json:"status"`                        // 任务状态
	Title          string    `json:"title"`                         // 任务标题
	Content        string    `json:"content"`                       // 数据主体
	Remark         string    `json:"remark"`                        // 备注
}

func (t Task) TableName() string {
	return "task"
}

func (t *Task) Load(tx *gorm.DB) error {
	if err := tx.Where("status = ?", Unload).First(t).Error; err != nil {
		return err
	}

	rst := tx.Model(t).Where("id = ?", t.ID).Update("status", Loaded)
	if rst.Error != nil {
		return rst.Error
	}

	if rst.RowsAffected == 0 {
		return ErrRowsAffected
	}
	return nil
}

func (t *Task) All(tx *gorm.DB) (task []Task) {
	tx.Find(&task)
	return task
}

func (t *Task) Loaded2Unload(tx *gorm.DB) error {
	return tx.Model(t).Where("status = ?", Loaded).Update("status", Unload).Error
}

func (t *Task) SetLineFinished(tx *gorm.DB, updates map[string]interface{}) error {
	rst := tx.Model(t).Where("id = ?", t.ID).Updates(updates)
	if rst.Error != nil {
		return rst.Error
	}

	if rst.RowsAffected == 0 {
		return ErrRowsAffected
	}

	return nil
}

func (t *Task) GetUnFinished(tx *gorm.DB) (lines []Task, err error) {
	tx.Where("status = ?", Loaded).Find(&lines)
	return lines, nil
}

func (t *Task) Write(tx *gorm.DB) error {
	rst := tx.Create(t)
	if rst.Error != nil {
		return rst.Error
	}
	if rst.RowsAffected == 0 {
		return ErrRowsAffected
	}
	return nil
}

func (t *Task) CountUnload(tx *gorm.DB) (count int64) {
	tx.Model(&Task{}).Where("status = ?", Unload).Count(&count)
	return count
}
